package com.example.zz.example.java.synchronizedtest;

/**
 * @author: zhuozhang6
 * @date: 2022/5/26
 * @email: zhuozhang6@iflytek.com
 * @Description: synchronized 锁分为类锁方法锁对象锁，见Something类
 * 对象锁作用范围：使用此对象锁的所有方法都是互斥的
 * 类锁作用范围：使用此类锁的所有方法都是互斥的
 * 类锁和对象锁相互没有影响
 *
 * 总结：所有持有该锁的方法互斥，类锁和对象锁相互没影响
 * 解释：
 * 锁的关键是，找准这个方法的锁到底是哪个
 * Something类中的方法锁、对象锁一，锁都是this，也就是该类的对象，外面new一个对象之后，这个对象在调用其内部的锁方法时，
 * 所有持有this锁的方法都是互斥的，所以两个线程中使用new出来的这个对象同时调用add方法互斥，两个线程同时调用add和add1也是互斥的，
 * 但是再new出个对象和之前的对象分别在两个线程同时调用add方法时，是不互斥的，因为锁不同，并且和调用add2不互斥，因为add2的锁是o，它与new出来的两个对象锁都不一样，
 * 它只与持有o的方法互斥
 * Something中的两个类锁，锁都是Something，不论哪个对象调用这个方法，锁都是不变的，相同方法或不同方法在不同线程中调用都是互斥的
 *
 */
public class SynchronizedDemo {
    public static void main(String[] args) {

//    public class Something(){
//        public synchronized void isSyncA(){}
//        public synchronized void isSyncB(){}
//        public static synchronized void cSyncA(){}
//        public static synchronized void cSyncB(){}
//    }

//        假如有Something类的两个实例x与y，那么下列各组方法被多线程同时访问的情况是怎样的？
//        a. x.isSyncA()与x.isSyncB()
//        b. x.isSyncA()与y.isSyncA()
//        c. x.cSyncA()与y.cSyncB()
//        d. x.isSyncA()与Something.cSyncA()

//        这里，很清楚的可以判断：
//        a，都是对同一个实例（x）的synchronized域访问，因此不能被同时访问。（多线程中访问x的不同synchronized域不能同时访问)
//        如果在多个线程中访问x.isSyncA()，因为仍然是对同一个实例，且对同一个方法加锁，所以多个线程中也不能同时访问。（多线程中访问x的同一个synchronized域不能同时访问)
//
//        b，是针对不同实例的，因此可以同时被访问（对象锁对于不同的对象实例没有锁的约束）
//
//        c，因为是static synchronized，所以不同实例之间仍然会被限制,相当于Something.cSyncA()与 Something.cSyncB()了，因此不能被同时访问。
//
//        第d呢?，答案是可以被同时访问的，答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定（lock）不同的原因。
//        个人分析也就是synchronized 与static synchronized 相当于两帮派，各自管各自，相互之间就无约束了，可以被同时访问。


    }
}
